package com.hkts.naturalgas.datahandler.sheldertask;

import com.google.gson.Gson;
import com.hkts.naturalgas.association.service.IHktsRequestAddressAssociationService;
import com.hkts.naturalgas.curvesettings.entity.Curve;
import com.hkts.naturalgas.curvesettings.entity.CurveSettings;
import com.hkts.naturalgas.curvesettings.entity.CurveState;
import com.hkts.naturalgas.curvesettings.service.*;
import com.hkts.naturalgas.datahandler.configurationfile.CurveConfig;
import com.hkts.naturalgas.datahandler.constance.EnviromentConstance;
import com.hkts.naturalgas.datahandler.constance.EnviromentCurveStateConstance;
import com.hkts.naturalgas.datahandler.constance.PowerFailureConstance;
import com.hkts.naturalgas.datahandler.curvecache.CurveCache;
import com.hkts.naturalgas.datahandler.utils.CurveFunctionUtils;
import com.hkts.naturalgas.datahandler.utils.GetRandomUtils;
import com.hkts.naturalgas.datahandler.utils.MiddleCurveFunctionUtils;
import com.hkts.naturalgas.datahandler.vo.AdjustmentVo;
import com.hkts.naturalgas.datahandler.vo.SimulationDataVo;
import com.hkts.naturalgas.dictionaries.entity.HktsEnvironmentProtectionDictionaries;
import com.hkts.naturalgas.dictionaries.entity.HktsEnvironmentProtectionItem;
import com.hkts.naturalgas.dictionaries.entity.HktsFieldControl;
import com.hkts.naturalgas.dictionaries.service.IHktsEnvironmentProtectionDictionariesService;
import com.hkts.naturalgas.dictionaries.service.IHktsEnvironmentProtectionItemService;
import com.hkts.naturalgas.dictionaries.service.IHktsFieldControlService;
import com.hkts.naturalgas.dictionaries.utils.DBUtils;
import com.hkts.naturalgas.updatetemperature.entity.HktsUpdateTemperature;
import com.hkts.naturalgas.updatetemperature.service.IHktsUpdateTemperatureService;
import com.hkts.naturalgas.utils.HttpAPIService;
import com.hkts.naturalgas.utils.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @ClassNameDataProductShelder
 * @Description
 * @Author yck
 * @Date2021-10-09 14:28
 * @Version V1.0
 **/
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
@Lazy(false)
@Slf4j
public class DataProductShelder {
    @Autowired
    public ICurveService iCurveService;
    @Autowired
    public CurveConfig curveConfig;
    @Autowired
    public IHktsCycleTimeService iHktsCycleTimeService;
    @Autowired
    public ICurveSettingsService iCurveSettingsService;
    @Autowired
    public IHktsEnvironmentProtectionDictionariesService iHktsEnvironmentProtectionDictionariesService;
    @Resource
    private HttpAPIService httpAPIService;

    @Autowired
    public IHktsEnvironmentProtectionItemService iHktsEnvironmentProtectionItemService;
    @Autowired
    public DBUtils dBUtils;
    @Autowired
    public ICurveStateService iCurveStateService;
    @Autowired
    public IHktsUpdateTemperatureService iHktsUpdateTemperatureService;
    @Autowired
    public IHktsRequestAddressAssociationService iHktsRequestAddressAssociationService;
    //各车间系统运行状态
    public Map<String, CurveState> curveState = new HashMap<String, CurveState>();
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    public IHktsFieldControlService iHktsFieldControlService;

    @Autowired
    public IHktsPowerFailureService iHktsPowerFailureService;
    //各车间系统运行状态
    public Map<String, HktsFieldControl> fieldControlMap = new HashMap<String, HktsFieldControl>();

    //sql集合用于最后批量处理insert sql
    public List<String> sqlList = new ArrayList<>();

    //CurveSettings集合用于最后批量处理
    public List<CurveSettings> curveSettingsList = new ArrayList<CurveSettings>();
    //用于http接口的表
    List<HktsEnvironmentProtectionDictionaries> httpList = new ArrayList<HktsEnvironmentProtectionDictionaries>();

    //用于MYSQL接口的表
    List<HktsEnvironmentProtectionDictionaries> mysqlList = new ArrayList<HktsEnvironmentProtectionDictionaries>();

    //用于封装所有的字段数据
    Map<String, List<HktsEnvironmentProtectionItem>> itemMap = new HashMap<String, List<HktsEnvironmentProtectionItem>>();
    //用于封装所有的曲线设置数据
    Map<String, List<CurveSettings>> curveSettingMap = new HashMap<String, List<CurveSettings>>();
    //曲线状况
    public Map<String, Curve> curveMap = new HashMap<String, Curve>();

    public List<Curve> updateCurveList = new ArrayList<Curve>();

    //停电标识
    public boolean isPowerFailer = false;
    //停燃气标识
    public boolean isGasFailer = false;

    //public int cycleTime=0;

    //设置燃气温度变化
    public Map<String, HktsUpdateTemperature> updateTemperatureMap = new HashMap<String, HktsUpdateTemperature>();

    //生成公用id
    String id = "";

    @Transactional
   // @Scheduled(cron = "*/2 * * * * ?")
    public void productData() throws Exception {
        log.info("---------数据同步开始----------");
        this.id = String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
        Long startTime = System.currentTimeMillis();
        List<CurveState> curveStates = iCurveStateService.selectList(null);
        curveState.clear();
        for (int i = 0; i < curveStates.size(); i++) {
            curveState.put(curveStates.get(i).getWorkShopId(), curveStates.get(i));
        }
        //需要控制值的字段
        HktsFieldControl control = new HktsFieldControl();
        List<HktsFieldControl> hktsFieldControls = iHktsFieldControlService.selectList(control);
        fieldControlMap = hktsFieldControls.stream().collect(Collectors.toMap(HktsFieldControl::getItemId, Function.identity()));
        //将所有表的数据加载到内存并进行分类
        HktsEnvironmentProtectionDictionaries hktsEnvironmentProtectionDictionaries = new HktsEnvironmentProtectionDictionaries();
        hktsEnvironmentProtectionDictionaries.setIsEnable(EnviromentConstance.IS_ENABLE);
        List<HktsEnvironmentProtectionDictionaries> hktsEnvironmentProtectionDictionaries1 = iHktsEnvironmentProtectionDictionariesService.selectList(hktsEnvironmentProtectionDictionaries);
        //将http表赋值
        httpList = hktsEnvironmentProtectionDictionaries1.stream().filter(hktsEnvironmentProtectionDictionarie -> EnviromentConstance.IS_HTTP.equals(hktsEnvironmentProtectionDictionarie.getIsHttp())).collect(Collectors.toList());
        //将mysql表赋值
        mysqlList = hktsEnvironmentProtectionDictionaries1.stream().filter(hktsEnvironmentProtectionDictionarie -> EnviromentConstance.IS_MYSQL.equals(hktsEnvironmentProtectionDictionarie.getIsHttp())).collect(Collectors.toList());
        //处理字段赋值部分逻辑
        itemMap = iHktsEnvironmentProtectionItemService.getItemMap(hktsEnvironmentProtectionDictionaries1);
        //封装曲线设置用到的字段
        curveSettingMap = iCurveSettingsService.selectMapforShelder(hktsEnvironmentProtectionDictionaries1);
        curveMap = iCurveService.selectMap();
        updateTemperatureMap = iHktsUpdateTemperatureService.selectUpdateStatusTemperature();
        sqlList.clear();
        //处理http接口
        //井新鸿翔不需要
        if (httpList.size() > 0) {
            httpHandler();
        }
        //判断是否停电或停气是则终止程序运行
        if (isPowerFailer||isGasFailer) {
            return;
        }
        //处理mysql数据
        mysqlHandler();
        //曲綫狀態更新
        iCurveSettingsService.updateBatchById(curveSettingsList);
        curveSettingsList.clear();
        //開啓綫程批量处理sql
        CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            try {
                dBUtils.updateBatch(sqlList);
                //批量处理曲线段设置
                for (int i = 0; i < curveStates.size(); i++) {
                    if (curveStates.get(i).getSystemCurveState().equals(EnviromentCurveStateConstance.STARTING)) {
                        curveStates.get(i).setSystemCurveState(EnviromentCurveStateConstance.START_UP);
                        iCurveStateService.updateById(curveStates.get(i));
                    }
                }
                if (updateCurveList.size() > 0) {
                    iCurveService.updateBatchById(updateCurveList);
                }
                List<HktsUpdateTemperature> hktsUpdateTemperatures=new ArrayList<>();
                for (String key : updateTemperatureMap.keySet()) {
                    HktsUpdateTemperature hktsUpdateTemperature = updateTemperatureMap.get(key);
                    hktsUpdateTemperature.setUpdateStatus(0);
                    hktsUpdateTemperature.setUpdateTime(LocalDateTime.now());
                    hktsUpdateTemperatures.add(hktsUpdateTemperature);
                }
                if(hktsUpdateTemperatures.size()>0){
                    iHktsUpdateTemperatureService.updateBatchById(hktsUpdateTemperatures);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, threadPoolExecutor);

        Long endTime = System.currentTimeMillis();
        Long tempTime = (endTime - startTime);
        log.info("定时任务花费时间：" +
                (((tempTime / 86400000) > 0) ? ((tempTime / 86400000) + "d") : "") +
                ((((tempTime / 86400000) > 0) || ((tempTime % 86400000 / 3600000) > 0)) ? ((tempTime % 86400000 / 3600000) + "h") : ("")) +
                ((((tempTime / 3600000) > 0) || ((tempTime % 3600000 / 60000) > 0)) ? ((tempTime % 3600000 / 60000) + "m") : ("")) +
                ((((tempTime / 60000) > 0) || ((tempTime % 60000 / 1000) > 0)) ? ((tempTime % 60000 / 1000) + "s") : ("")) +
                ((tempTime % 1000) + "ms"));
        log.info("---------数据同步结束---------");
    }

    public void httpHandler() throws Exception {
        //TODO 判断当前的运行状态
        Map<String, Object> result = new HashMap<String, Object>();
        String s = "";
        try {
            //假Ip
            //s = httpAPIService.doGet("http://192.168.99.67:5000//biz");
            //真地址
          s = httpAPIService.doGet("http://192.168.205.4:5000//biz");
        } catch (Exception e) {
            e.printStackTrace();
            isPowerFailer = true;
            return;
        }

        Gson gson = new Gson();
        Map map = new HashMap();
        map = gson.fromJson(s, map.getClass());
        //判断是否停电,停电终止程序运行
        if (checkForPowerfailure(map)) {
            return;
        }
        Map data = (Map) map.get("data");

        //TODO 检验是否停气
        checkForGasfailure();

        //实时更新炉号
        CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            try {
                iCurveService.updateHeadNum(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, threadPoolExecutor);
        //循環所有http表，組裝成map到數據處理方法
        for (int i = 0; i < httpList.size(); i++) {
            //根据车间判断当前车间是否在停机状态如果是则直接跳过不进行下边逻辑&&!list.get(i).getId().equals("7")
            if (curveState.get(httpList.get(i).getWorkShop()) != null && curveState.get(httpList.get(i).getWorkShop()).getSystemCurveState().equals(EnviromentCurveStateConstance.SHUT_DOWN)) {
                continue;
            }
            List<HktsEnvironmentProtectionItem> tableItemByTableId = itemMap.get(httpList.get(i).getId());
            Map<String, Object> save = new HashMap<String, Object>();
            for (int j = 0; j < tableItemByTableId.size(); j++) {
                if (!tableItemByTableId.get(j).getDataType().equals(EnviromentConstance.DATE_TIME)) {
                    save.put(tableItemByTableId.get(j).getFieldName(), data.get(tableItemByTableId.get(j).getCorrespondingField()));
                }
            }
            //保存数据逻辑
            checkIsNeedSimulation(httpList.get(i).getWorkShop(), httpList.get(i).getCurveId(), httpList.get(i).getTableName(), tableItemByTableId, save);
        }
    }

    /**
     * 功能描述:
     * 处理mysql同步问题
     *
     * @return: void
     * @Author: 杨春科
     * @Date: 2021-10-11 16:36
     * @Description //处理数据可同步逻辑
     */
    public void mysqlHandler() throws ParseException {
        // List<HktsEnvironmentProtectionDictionaries> dbTable = iHktsEnvironmentProtectionDictionariesService.getDbTable();
        for (int i = 0; i < mysqlList.size(); i++) {
            Long startTime = System.currentTimeMillis();
            //根据车间判断当前车间是否在停机状态如果是则直接跳过不进行下边逻辑
            if (curveState.get(mysqlList.get(i).getWorkShop()) != null && curveState.get(mysqlList.get(i).getWorkShop()).getSystemCurveState().equals(EnviromentCurveStateConstance.SHUT_DOWN)) {
                log.info("车间号{}进入停机状态", mysqlList.get(i).getWorkShop());
                continue;
            }
            List<HktsEnvironmentProtectionItem> tableItemByTableId = itemMap.get(mysqlList.get(i).getId());
            List<String> list = new ArrayList<>();
            List<String> listFiled = new ArrayList<>();
            for (int j = 0; j < tableItemByTableId.size(); j++) {
                if (!tableItemByTableId.get(j).getDataType().equals(EnviromentConstance.DATE_TIME)) {
                    list.add(tableItemByTableId.get(j).getFieldName());
                    listFiled.add(tableItemByTableId.get(j).getCorrespondingField());
                }
            }
            try {
                Map<String, Object> associations = iHktsRequestAddressAssociationService.getAssociations(mysqlList.get(i), list, listFiled);

                Long endTime = System.currentTimeMillis();
                Long tempTime = (endTime - startTime);
                log.info("单表查询时间：" +
                        (((tempTime / 86400000) > 0) ? ((tempTime / 86400000) + "d") : "") +
                        ((((tempTime / 86400000) > 0) || ((tempTime % 86400000 / 3600000) > 0)) ? ((tempTime % 86400000 / 3600000) + "h") : ("")) +
                        ((((tempTime / 3600000) > 0) || ((tempTime % 3600000 / 60000) > 0)) ? ((tempTime % 3600000 / 60000) + "m") : ("")) +
                        ((((tempTime / 60000) > 0) || ((tempTime % 60000 / 1000) > 0)) ? ((tempTime % 60000 / 1000) + "s") : ("")) +
                        ((tempTime % 1000) + "ms"));
                if (associations.get("code").toString().equals("200")) {
                    //保存数据逻辑
                    checkIsNeedSimulation(mysqlList.get(i).getWorkShop(), mysqlList.get(i).getCurveId(), mysqlList.get(i).getTableName(), tableItemByTableId, associations);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 功能描述:
     * 处理判断是否需要仿真数据逻辑
     *
     * @return:
     * @Author: 杨春科
     * @Date: 2021-10-11 16:38
     * @Description //TODO
     */
    public void checkIsNeedSimulation(String work_shop, String curveId, String tableName, List<HktsEnvironmentProtectionItem> list, Map<String, Object> map) throws ParseException {
        List<HktsEnvironmentProtectionItem> collect = list.stream().filter(hktsEnvironmentProtectionItem -> EnviromentConstance.DEAL_WITH.equals(hktsEnvironmentProtectionItem.getNeedDeal())).collect(Collectors.toList());
        //需要单独控制的字段
        List<HktsEnvironmentProtectionItem> controllList = list.stream().filter(hktsEnvironmentProtectionItem ->
                EnviromentConstance.FIXED_VALUE.equals(hktsEnvironmentProtectionItem.getNeedDeal())
                        || EnviromentConstance.SECTION.equals(hktsEnvironmentProtectionItem.getNeedDeal())
                        || EnviromentConstance.COEFFICIENT.equals(hktsEnvironmentProtectionItem.getNeedDeal()))
                .collect(Collectors.toList());
        // map = iHktsFieldControlService.hanglerItem(controllList, map);
        map = handlerControllerFiled(map, controllList);

        Map<String, Object> lastRow = dBUtils.getLastRow(tableName);
        // SimulationDataVo simulationData = getSimulationData(curveId);

        if (curveState.get(work_shop) == null || curveState.get(work_shop).getSystemCurveState().equals(EnviromentCurveStateConstance.SWITCHING_COMPLETE)) {
            //车间号没有曲线规则或者已经切换完成 数据直接保存
            log.info(tableName, "切换完成，数据直接保存！！！！");
            if (StringUtils.isNotBlank(curveId)) {
                SimulationDataVo simulationData = getSimulationData(curveId);
            }
        } else if (isGasFailer) {
            log.info("系统状态：天然气断气状态中！！！！");
            //当系统处于天然气断气状态业务处理
            for (int i = 0; i < collect.size(); i++) {
                if (lastRow.get(collect.get(i).getFieldName()) != null) {
                    Float value = Float.parseFloat(lastRow.get(collect.get(i).getFieldName()).toString());
                    float offsetData = GetRandomUtils.getOffsetData(60, 1);
                    if (offsetData > curveConfig.getTimeInterval().intValue()) {
                        map.put(collect.get(i).getFieldName(), value);
                    } else {
                        map.put(collect.get(i).getFieldName(), value - 1);
                    }
                }
            }
        } else if (curveState.get(work_shop).getSystemCurveState().equals(EnviromentCurveStateConstance.STARTING)) {
            SimulationDataVo simulationData = getSimulationData(curveId);
            for (int i = 0; i < collect.size(); i++) {
                float data = handelerSimulationData(i, collect.size(), simulationData.getValue());
                map.put(collect.get(i).getFieldName(), data);
            }
        } else if (curveState.get(work_shop).getSystemCurveState().equals(EnviromentCurveStateConstance.RECOVERY)) {
            log.info("系统状态，正在恢复！！！！");
            CurveState curveState = this.curveState.get(work_shop);
            LocalDateTime switchBeginTime = curveState.getSwitchBeginTime();
            //时间加
            LocalDateTime localDateTime = switchBeginTime.plusMinutes(curveConfig.getRecorverTime());
            SimulationDataVo simulationData = getSimulationData(curveId);
            if (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() > localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()) {
                log.info("时间超过默认时间，由恢复切换为正常启动状态");
                curveState.setSystemCurveState(EnviromentCurveStateConstance.START_UP);
                iCurveStateService.updateById(curveState);
                for (int i = 0; i < collect.size(); i++) {
                    float data = handelerSimulationData(i, collect.size(), simulationData.getValue());
                    map.put(collect.get(i).getFieldName(), data);
                }
            } else {
                //当前时间差的秒数
                long seconds = (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() - switchBeginTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()) / 1000;
                //需要切换总的秒数
                long totalSecond = 60 * curveConfig.getRecorverTime();
                for (int i = 0; i < collect.size(); i++) {
                    //系统处于仿真系统启动状态
                    Float data = handelerSimulationData(i, collect.size(), simulationData.getValue());
                    float v = map.get(collect.get(i).getFieldName()) == null ? 0 : Float.parseFloat(map.get(collect.get(i).getFieldName()).toString());
                    float rate = ((float) seconds / (float) totalSecond);
                    data = v + (data - v) * rate;
                    map.put(collect.get(i).getFieldName(), data.intValue());
                }
            }
        } else if (curveState.get(work_shop).getSystemCurveState().equals(EnviromentCurveStateConstance.START_UP)) {
            log.info("系统状态：正常启动！！！！");
            if (StringUtils.isNotBlank(curveId)) {
                //计算仿真相关数据
                SimulationDataVo simulationData = getSimulationData(curveId);
                // log.info("车间号：{}", work_shop, "表名：{}", tableName, "数据仿正在启动");
                Curve curve = curveMap.get(curveId);
                HktsUpdateTemperature hktsUpdateTemperature = updateTemperatureMap.get(curve.getFlameSystem());
                if (hktsUpdateTemperature != null) {
                    //燃烧架
                    for (int i = 0; i < collect.size(); i++) {
                        float i1 = Float.parseFloat(lastRow.get(collect.get(i).getFieldName()).toString());
                        if (curve.getType().equals("1")) {
                            i1 = hktsUpdateTemperature.getBurnTemperature() + i1 < 0 ? 0 : hktsUpdateTemperature.getBurnTemperature() + i1;
                        } else {
                            i1 = hktsUpdateTemperature.getSmokeTemperature() + i1 < 0 ? 0 : hktsUpdateTemperature.getSmokeTemperature() + i1;
                        }
                        lastRow.put(collect.get(i).getFieldName(), i1);
                    }
                }

                for (int i = 0; i < collect.size(); i++) {
                    //判断是否为开始值以及是否有上一条记录,如果不需要重新开始
                    if (simulationData.getIsStop().equals(EnviromentCurveStateConstance.IS_STOP)) {
                        map.put(collect.get(i).getFieldName(), 0);
                    } else if (simulationData.getIsBegin().equals(EnviromentCurveStateConstance.IS_BEGIN) || lastRow == null) {
                        float data = handelerSimulationData(i, collect.size(), simulationData.getValue());
                        map.put(collect.get(i).getFieldName(), data);
                        //每条曲线重新开始是需要重新清除缓存
                        if (simulationData.getIsBegin().equals(EnviromentCurveStateConstance.IS_BEGIN)) {
                            if (CurveCache.functionCache.containsKey(collect.get(i).getFieldName())) {
                                CurveCache.functionCache.remove(collect.get(i).getFieldName());
                            }
                        }
                    } else {
                        float value = 0;
                        //根据上一条记录值 速率 计算当条记录的值
                        if (collect.get(i).getFieldName() != null && lastRow.get(collect.get(i).getFieldName()) != null) {
                            value = Float.parseFloat(lastRow.get(collect.get(i).getFieldName()).toString());
                        }
                        //判断是否在温度调整阶段
                        if (simulationData.getIsAdjustment().equals(EnviromentCurveStateConstance.IS_ADJUSTMENT) && !simulationData.getIsKeep().equals(EnviromentCurveStateConstance.IS_KEEP)) {
                            //判断上一条记录是否等于最高温度，如果大于减，小于则加，等于则加减一个速率
                            AdjustmentVo vo = new AdjustmentVo(value, simulationData.getTemperature(), simulationData.getLastRateSeconds(), i, collect.size(), collect.get(i).getFieldName(),
                                    simulationData.getTotalSeconds(), simulationData.getCurrentSeconds());
                            map.put(collect.get(i).getFieldName(), dataAdjustment(vo));
                        } else if (simulationData.getIsAdjustment().equals(EnviromentCurveStateConstance.IS_ADJUSTMENT) && simulationData.getIsKeep().equals(EnviromentCurveStateConstance.IS_KEEP)) {
                            AdjustmentVo vo = new AdjustmentVo(value, simulationData.getTemperature(), simulationData.getLastRateSeconds(), i, collect.size(), collect.get(i).getFieldName(),
                                    simulationData.getTotalSeconds(), simulationData.getCurrentSeconds());
                            map.put(collect.get(i).getFieldName(), dataKeep(vo));
                        } else {
                            AdjustmentVo vo = new AdjustmentVo(value, simulationData.getTemperature(), simulationData.getRateSection(), i, collect.size(), collect.get(i).getFieldName(),
                                    simulationData.getTotalSeconds(), simulationData.getCurrentSeconds());
                            //校验当前的温度是否大于下个节点的温度
                            map.put(collect.get(i).getFieldName(), MiddleCurveFunctionUtils.CurveFunctionHandler(vo, simulationData));
                            //清除缓存的key
                        }
                    }
                }
            }
            int count = 0;
            //判断需要处理的阶段是否等于0如果是0 将其他值全部赋值为0
            for (int i = 0; i < collect.size(); i++) {
                float v = Float.parseFloat(map.get(collect.get(i).getFieldName()).toString());
                if (v == 0) {
                    count = i + 1;
                }
            }
            //判断当曲线值多个为0时将开度功率也赋值为0
            if (count > 5) {
                for (int i = 0; i < list.size(); i++) {
                    if (!list.get(i).getFieldName().equals("time")) {
                        map.put(list.get(i).getFieldName(), 0);
                    }
                }
            }
        } else {
            log.info("系统状态：切换过程中！！！！");
            //数据切换阶段
            CurveState curveState = this.curveState.get(work_shop);
            LocalDateTime switchBeginTime = curveState.getSwitchBeginTime();
            //时间加
            LocalDateTime localDateTime = switchBeginTime.plusMinutes(curveState.getSwitchingTime());
            //判断时间差是否超过当前时间如果超过则取实际数据并修改当前的曲线规则

            if (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() >= localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()) {
                curveState.setSystemCurveState(EnviromentCurveStateConstance.SWITCHING_COMPLETE);
                iCurveStateService.updateById(curveState);
            } else {
                if (StringUtils.isNotBlank(curveId)) {
                    SimulationDataVo simulationData = getSimulationData(curveId);
                    Float value = simulationData.getValue();
                    //当前时间差的秒数
                    long seconds = (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() - switchBeginTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()) / 1000;
                    //需要切换总的秒数
                    long totalSecond = 60 * curveState.getSwitchingTime();
                    log.info("当前的时间差：{}", seconds);
                    log.info("总的时间差{}", totalSecond);
                    for (int i = 0; i < collect.size(); i++) {
                        //系统处于仿真系统启动状态
                        log.info(tableName, "数据仿正在切换");
                        if (lastRow == null) {
                            //  log.info(tableName, "无上调记录时");
                            value = handelerSimulationData(i, collect.size(), value);
                            float v = Float.parseFloat(map.get(collect.get(i).getFieldName()).toString());
                            //  log.info("仿真数据计算之前：{}", simulationData);
                            float rate = ((float) seconds / (float) totalSecond);
                            //  log.info("目前比例：{}", rate);
                            value = value + (v - value) * rate;
                            // log.info("仿真数据计算之后：{}", value);
                            map.put(collect.get(i).getFieldName(), value);
                        } else {
                            //log.info(tableName, "切换有上条记录时");
                            value = Float.parseFloat(lastRow.get(collect.get(i).getFieldName()).toString());
                            // log.info("上一条记录：{}", value);
                            float v = collect.get(i).getFieldName() == null ? 0 : Float.parseFloat(map.get(collect.get(i).getFieldName()).toString());
                            // log.info("目前真实数据：{}", v);
                            float rate = ((float) seconds / (float) totalSecond);
                            //log.info("目前比例：{}", rate);
                            // log.info("(value - v) * rate：{}", (value - v) * rate);
                            value = value + (v - value) * rate;
                            //log.info("仿真数据计算之后：{}", value);
                            map.put(collect.get(i).getFieldName(), value.intValue());
                        }
                    }
                }
            }
        }
        //缓存处理
        CurveCache.lastRowCache.put(tableName, map);
        //将sql放在集合中用于最后的批量处理
        sqlList.add(dBUtils.updateSql(tableName, list, map, String.valueOf(id)));
    }


    /**
     * 功能描述:
     *
     * @return: float
     * @Author: 杨春科
     * @Date: 2021-10-11 17:19
     * @Description //  判断火道调整温度  最两侧火道温度低
     * 当参数为0时返回0，当参数经过处理后小于0时返回0
     */
    public float handelerSimulationData(int index, int size, float value) {
        //log.info("原值：{}", value);
        if (value == 0) {
            return value;
        }
        if (index == 0 || index == size - 1) {
            value = value - GetRandomUtils.getOffsetData(30, 12);
        } else {
            value = value + (10 - GetRandomUtils.getOffsetData(20, 1));
        }
        if (value < 0) {
            return 0;
        }
        int round = Math.round(value);
        return round;
    }


    /**
     * 功能描述:
     * 获取仿真数据的理论值，根据燃烧系统种类，节点 设置当前节点的状态
     *
     * @return: float
     * @Author: 杨春科
     * @Date: 2021-10-11 16:21
     * @Description
     */
    public SimulationDataVo getSimulationData(String curveId) {
        SimulationDataVo vo = new SimulationDataVo();
        CurveSettings curveSettings = new CurveSettings();
        curveSettings.setCurveId(curveId);
        List<CurveSettings> curveSettings1 = curveSettingMap.get(curveId);
        int index = 0;
        for (int i = 0; i < curveSettings1.size(); i++) {
            //找到当前所在节点
            if (curveSettings1.get(i).getCurrentNode().equals("1")) {
                index = i;
                break;
            }
        }
        // 判断当前值是否为第一节点 秒速乘时间间隔为每次执行的速度
        Float rateSeconds = curveSettings1.get(index).getRateSeconds() == null ? 0 : curveSettings1.get(index).getRateSeconds();
        vo.setRateSeconds(rateSeconds);
        vo.setRateSection(rateSeconds * curveConfig.getTimeInterval().intValue());
        vo.setCurrentSeconds(curveSettings1.get(index).getCurrentSeconds());
        vo.setTotalSeconds(curveSettings1.get(index).getTotalSeconds());
        vo.setType(curveSettings1.get(index).getType());

        float v = dataHandlerCurveSettings(index, curveSettings1);
        vo.setValue(v);
        //是否重新开始
        if (curveMap.get(curveId).getIsBegin().equals(EnviromentCurveStateConstance.IS_BEGIN)) {
            vo.setIsBegin(EnviromentCurveStateConstance.IS_BEGIN);
            curveMap.get(curveId).setIsBegin(EnviromentCurveStateConstance.IS_NOT_BEGIN);
            updateCurveList.add(curveMap.get(curveId));
        }
        if (index == 0 && curveSettings1.get(index).getCurrentSeconds().intValue() == curveConfig.getTimeInterval().intValue()) {
            vo.setIsBegin(EnviromentCurveStateConstance.IS_BEGIN);
        }
        //修改 由燃烧架需要停止阶段修改为燃烧架，排烟架都需要
        if (index == curveSettings1.size() - 2) {
            vo.setIsStop(EnviromentCurveStateConstance.IS_STOP);
        }
        if (index == curveSettings1.size() - 3 && curveSettings1.get(index).getType().equals(EnviromentConstance.IS_RS)) {
            float lastRateSeconds = curveSettings1.get(index - 1).getRateSeconds() == null ? 0 : curveSettings1.get(index - 1).getRateSeconds();
            vo.setLastRateSeconds(lastRateSeconds * curveConfig.getTimeInterval().intValue());
            vo.setIsAdjustment(EnviromentCurveStateConstance.IS_ADJUSTMENT);
            vo.setCurveSettingsId(curveSettings1.get(index - 1).getId());
            //时间大于总时间的3分之一时处于温度保持阶段
            if ((float) curveSettings1.get(index).getCurrentSeconds().intValue() / (float) curveSettings1.get(index).getTotalSeconds().intValue() > 0.3) {
                vo.setIsKeep(EnviromentCurveStateConstance.IS_KEEP);
            }
        }
        //当前节点不是最后一个节点时
        if (index != curveSettings1.size() - 1) {
            vo.setNextTemperature(curveSettings1.get(index + 1).getTemperature());
        }
        vo.setTemperature(curveSettings1.get(index).getTemperature());
        vo.setIndex(index);
        return vo;
    }

    /**
     * 功能描述:
     * [index, curveSettings1]
     *
     * @return: float
     * @Author: 杨春科
     * @Date: 2021-10-11 21:11
     * @Description //  处理流程设置 返回当前时间点的数据
     */

    public float dataHandlerCurveSettings(int index, List<CurveSettings> curveSettings1) {
        // log.info("节点节点：{}", index);
        CurveSettings curveSettings = curveSettings1.get(index);
        Float temperature = curveSettings.getTemperature();
        //  log.info("节点温度：{}", temperature);
        Float currentTemperature = 0F;
        currentTemperature = temperature + curveSettings.getRateSeconds() * (curveSettings.getCurrentSeconds() + curveConfig.getTimeInterval());
        //log.info("当前温度：{}", currentTemperature);
        curveSettings.setCurrentSeconds(curveSettings.getCurrentSeconds() + curveConfig.getTimeInterval());
        //当前节点时间再增加需要跳转到下个节点时
        if (curveSettings.getCurrentSeconds() >= curveSettings.getTotalSeconds()) {
            //将当前节点设置为非当前节点
            curveSettings.setCurrentNode(EnviromentConstance.IS_NOT_CURRENT_NODE);
            curveSettings.setCurrentSeconds(0);
            //将next node 设置为当前节点逻辑
            //如果next node 时间为最后一个节点则直接跳过为0
            if (index + 1 == curveSettings1.size() - 1) {
                CurveSettings curveSettings2 = curveSettings1.get(0);
                curveSettings2.setCurrentNode(EnviromentConstance.IS_CURRENT_NODE);
                curveSettings2.setCurrentSeconds(0);
                //curveSettingsMapper.updateById(curveSettings2);
                curveSettingsList.add(curveSettings2);
            } else {
                CurveSettings curveSettings2 = curveSettings1.get(index + 1);
                curveSettings2.setCurrentNode(EnviromentConstance.IS_CURRENT_NODE);
                curveSettings2.setCurrentSeconds(0);
                //curveSettingsMapper.updateById(curveSettings2);
                curveSettingsList.add(curveSettings2);
            }
            //判断是否为倒数第二条记录 如果是 燃烧架时间段要重新生成12-30的随机数
            //20211021 由燃烧架修改为燃烧和排烟架都需要移架过程
            if (index + 1 == curveSettings1.size() - 2) {
                float movingFrameTime = GetRandomUtils.getMovingFrameTime();
                //最后一条记录
                CurveSettings curveSettings2 = curveSettings1.get(curveSettings1.size() - 1);
                CurveSettings curveSettings3 = curveSettings1.get(curveSettings1.size() - 2);
                curveSettings2.setTimePoint(curveSettings3.getTimePoint() + movingFrameTime);
                //curveSettingsMapper.updateById(curveSettings2);
                curveSettingsList.add(curveSettings2);
                //最后第二记录条记录
                // log.info("倒数第二条随机小时：{}", movingFrameTime);
                movingFrameTime = 3600 * movingFrameTime;
                Integer totalSeconds = (int) movingFrameTime;
                // log.info("倒数第二条随机总秒数：{}", totalSeconds);
                curveSettings3.setTotalSeconds(totalSeconds);
                curveSettings3.setCurrentSeconds(0);
                //curveSettingsMapper.updateById(curveSettings3);
                curveSettingsList.add(curveSettings3);
                //移驾过程中所有数据

            }
        } else {
            //正常增加
            if (index == curveSettings1.size() - 2 && curveSettings.getType().equals(EnviromentConstance.IS_RS)) {
                currentTemperature = 0f;
            }
        }
        //更新当前记录数据
        // curveSettingsMapper.updateById(curveSettings);
        //补偿currentNode丢失node等于1
        curveSettingsList.add(curveSettings);
        return currentTemperature;
    }

    /**
     * 功能描述:
     * [lastRowValue, temperature, rate]
     *
     * @return: float
     * @Author: 杨春科
     * @Date: 2021-10-17 11:31
     * @Description //数据调整阶段
     */
    public float dataAdjustment(AdjustmentVo vo) {
        if (vo.getItemIndex() != 0 && vo.getItemIndex() != vo.getItemNum() - 1) {
            if (vo.getLastRowValue() < vo.getTemperature()) {
                vo.setLastRowValue(vo.getLastRowValue() + GetRandomUtils.getWhetherCarry(vo.getLastRateSeconds()));
            } else if (vo.getLastRowValue() > vo.getTemperature()) {
                vo.setLastRowValue(vo.getLastRowValue() - GetRandomUtils.getWhetherCarry(vo.getLastRateSeconds()));
            } else {
                vo.setLastRowValue(vo.getLastRowValue() + GetRandomUtils.getRandom());
            }
        } else {
            //设置随机上升下降曲线
            vo.setLastRowValue(CurveFunctionUtils.CurveFunctionHandler(vo));
        }
        return vo.getLastRowValue();
    }

    /**
     * 功能描述:
     * [lastRowValue, temperature, rate]
     *
     * @return: float
     * @Author: 杨春科
     * @Date: 2021-10-17 11:31
     * @Description //数据调整阶段
     */
    public float dataKeep(AdjustmentVo vo) {
        if (vo.getItemIndex() != 0 && vo.getItemIndex() != vo.getItemNum() - 1) {
            if (vo.getLastRowValue() - vo.getTemperature() > 5) {
                vo.setLastRowValue(vo.getLastRowValue() - 1);
                ;
            } else if (vo.getLastRowValue() - vo.getTemperature() < -7) {
                vo.setLastRowValue(vo.getLastRowValue() + 1);
            } else {
                vo.setLastRowValue(vo.getLastRowValue() + GetRandomUtils.getRandom());
            }
        } else {
            vo.setLastRowValue(CurveFunctionUtils.CurveFunctionHandler(vo));
        }
        return vo.getLastRowValue();
    }

    /**
     * 功能描述:
     * [map, list]
     *
     * @return: float
     * @Author: 杨春科
     * @Date: 2021-10-17 11:31
     * @Description //需要单独控制的字段
     */
    public Map<String, Object> handlerControllerFiled(Map<String, Object> map, List<HktsEnvironmentProtectionItem> list) {
        for (int i = 0; i < list.size(); i++) {
            Object value = map.get(list.get(i).getFieldName());
            if (list.get(i).getNeedDeal().equals(EnviromentConstance.COEFFICIENT)) {
                float coefficent = Float.parseFloat(fieldControlMap.get(list.get(i).getId()).getCoefficient().toString());
                if (value != null) {
                    map.put(list.get(i).getFieldName(), coefficent * Float.parseFloat(value.toString()));
                }
            } else if (list.get(i).getNeedDeal().equals(EnviromentConstance.FIXED_VALUE)) {
                map.put(list.get(i).getFieldName(), fieldControlMap.get(list.get(i).getId()).getFixedValue());
            } else if (list.get(i).getNeedDeal().equals(EnviromentConstance.SECTION)) {
                float max = fieldControlMap.get(list.get(i).getId()).getMaxValue();
                float min = fieldControlMap.get(list.get(i).getId()).getMinValue();
                float offsetData = GetRandomUtils.getOffsetData(max, min);
                map.put(list.get(i).getFieldName(), offsetData);
            }
        }
        return map;
    }

    //校验是否停电
    public boolean checkForPowerfailure(Map<String, Object> map) throws ParseException {
        if (map == null) {
            isPowerFailer = true;
        } else {
            map = (Map) map.get("data");
            boolean bool = true;
            Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> next1 = iterator.next();
                String key = next1.getKey();
                Object value = next1.getValue();
                //测试停电业务需要将一下判读依据注释
                if (value != null && Float.parseFloat(value.toString()) != 0) {
                    bool = false;
                    break;
                }
            }
            isPowerFailer = bool;
        }
        //如果停电执行停电的业务
        if (isPowerFailer) {
            curveSettingMap = iHktsPowerFailureService.handlerPowerFailure(PowerFailureConstance.POWER_FAILURE,
                    httpList, itemMap, curveSettingMap, LocalDateTime.now()
            );
        }
        return isPowerFailer;
    }

    //校验是否停气
    public boolean checkForGasfailure() throws ParseException {

        HktsEnvironmentProtectionDictionaries hktsEnvironmentProtectionDictionaries = mysqlList.stream().filter(hktsEnvironmentProtectionDictionarie -> "24".equals(hktsEnvironmentProtectionDictionarie.getId())).collect(Collectors.toList()).get(0);

        List<HktsEnvironmentProtectionItem> tableItemByTableId = itemMap.get("24");
        List<String> list = new ArrayList<>();
        List<String> listFiled = new ArrayList<>();
        for (int j = 0; j < tableItemByTableId.size(); j++) {
            if (!tableItemByTableId.get(j).getDataType().equals(EnviromentConstance.DATE_TIME)) {
                list.add(tableItemByTableId.get(j).getFieldName());
                listFiled.add(tableItemByTableId.get(j).getCorrespondingField());
            }
        }
        try {
            //isGasFailer = true;
            Map<String, Object> associations = iHktsRequestAddressAssociationService.getAssociations(hktsEnvironmentProtectionDictionaries, list, listFiled);
            // 确定数据库字段，判断是否停气
            if (Float.parseFloat(associations.get("qb_1_bk").toString()) == 0 && Float.parseFloat(associations.get("qb_2_bk").toString()) == 0) {
                isGasFailer = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (isGasFailer) {
          curveSettingMap = iHktsPowerFailureService.handlerPowerFailure(PowerFailureConstance.GAS_FAILURE,
                    httpList, itemMap, curveSettingMap, LocalDateTime.now() );
            for(int i=0;i<httpList.size();i++){
                if(StringUtils.isNotBlank(httpList.get(i).getCurveId())){
                    getSimulationData(httpList.get(i).getCurveId());
                }
            }
            // 曲线段往下走
            iCurveSettingsService.updateBatchById(curveSettingsList);

        } else {
            curveSettingMap = iHktsPowerFailureService.handlerPowerFailure(PowerFailureConstance.SYSTEM_NORMAL,
                    httpList, itemMap, curveSettingMap, LocalDateTime.now()
            );
        }
        return isGasFailer;
    }
}
